Hoy inauguramos la serie anual de Playtime a escala mundial con eventos consecutivos en Berlín y San Francisco. 2017 es un año increíble para los programadores en Google Play. Durante el mes próximo, nos enteraremos de cómo les está yendo a muchos programadores de apps y juegos de distintas ciudades de todo el mundo. Es un año excelente para los programadores en Google Play, y ahora hay más de 8,000 millones de instalaciones nuevas por mes en todo el mundo.

Hoy inauguramos la serie anual de Playtime a escala mundial con eventos consecutivos en Berlín y San Francisco. 2017 es un año increíble para los programadores en Google Play. Durante el mes próximo, nos enteraremos de cómo les está yendo a muchos programadores de apps y juegos de distintas ciudades de todo el mundo. Es un año excelente para los programadores en Google Play, y ahora hay más de 8,000 millones de instalaciones nuevas por mes en todo el mundo.


Para ayudarte a seguir aprovechando esta oportunidad, anunciamos innovaciones en Google Play y nuevas características en Play Console. Síguenos en Medium, donde los presentadores publicarán sus estrategias, prácticas recomendadas y ejemplos para ayudarte a alcanzar tus objetivos de negocio. A medida que crece Google Play, deseamos ayudar a los usuarios a comprender nuestro negocio. Por eso, publicamos también el informe State of Play 2017, que se actualizará anualmente y te ayudará a mantenerte informado sobre el progreso de Play y la ayuda que ofrecemos a los programadores para que alcancen el éxito.


Google Play les da vida a todos tus dispositivos, ya sean teléfonos y tablets, dispositivos Wear, TV, Daydream o Chromebook, como el nuevo dispositivo Google Pixelbook. Ahora es más fácil que los usuarios descubran contenido excelente y vuelvan a participar en Play Store.



Google Cloud Platform (GCP) es un espacio ideal para ejecutar tus cargas de trabajo .NET y mejoró aún más con la última versión de Cloud Tools para la extensión de Visual Studio, Cloud Tools para Powershell y nuestro tiempo de ejecución de ASP.NET Core para App Engine Flexible.


Google Cloud Platform (GCP) es un espacio ideal para ejecutar tus cargas de trabajo .NET y mejoró aún más con la última versión de Cloud Tools para la extensión de Visual Studio, Cloud Tools para Powershell y nuestro tiempo de ejecución de ASP.NET Core para App Engine Flexible.

Cloud Tools para Visual Studio 


Integramos los visores de extensiones para Stackdriver Logging y Stackdriver Error Reporting a Visual Studio para ayudarte a diagnosticar problemas y controlar tu código. También mejoramos Cloud Explorer con una integración más profunda de Google Cloud Storage y Google Cloud Pub/Sub, a fin de que puedas administrar tus recursos sin abandonar Visual Studio.
Integración de Stackdriver 

A veces, incluso el mejor código experimenta desperfectos en la producción. Para ayudarte a realizar un diagnóstico de lo que sucede, integramos Stackdriver Logging y Stackdriver Error Reporting a Visual Studio, para que puedas encontrar la fuente del problema mientras esté abierta tu solución de Visual Studio.

Independientemente de que tu app esté basada en ASP.NET 4.x o ASP.NET Core, si usas Stackdriver Logging para registrar tu app .NET, ahora puedes explorar las entradas de registro que esta generó directamente en Visual Studio:
También puedes realizar consultas de los registros que se originen de una versión y un servicio determinados en Google App Engine (como se muestra en la imagen anterior) o explorar las entradas de registro que provengan de una VM determinada de Compute Engine.

Lo que es aún mejor, si usas nuestro paquete NuGet de Google.Cloud.Logging.V2 para enviar las entradas de registro, la extensión puede hacer coincidir las entradas de registro con las líneas de código fuente en las que se originaron. La extensión intenta obtener la versión exacta del código fuente de git, lo cual te permite ver exactamente el origen de la entrada de registro. Consulta la documentación del visor de registros de Stackdriver para obtener más detalles sobre cómo usar esta característica.

¿Qué sucede cuando tu app falla? En este punto, entra en escena Stackdriver Error Reporting. Si tu aplicación usa Stackdriver Error Reporting para enviar informes de errores a Stackdriver, ahora puedes explorar estos informes directamente desde Visual Studio:

Puedes ver los errores más frecuentes y el seguimiento de pila completo del error, e incluso ir directamente a la línea de código fuente en la que se originó el error. Para obtener información más detallada, consulta la sección del visor de errores de Stackdriver.

Mejoras de Cloud Explorer 

Comprendemos tu deseo de permanecer en Visual Studio cuando trabajas con tus apps, porque la entrada y la salida de Visual Studio es un cambio grande de contexto. Para ello, seguimos mejorando nuestra propia Cloud Explorer para que puedas administrar los recursos más importantes directamente desde Visual Studio. En la última versión, agregamos una integración más profunda con Cloud Storage y un nodo nuevo para administrar tus recursos de Cloud Pub/Sub.

Veamos lo que puedes hacer ahora con la integración de Cloud Storage. Siempre pudiste ver directamente en Cloud Explorer los depósitos que existían en el proyecto actual. Ahora, también puedes abrir los depósitos y consultar los archivos almacenados dentro de ellos, y tratar a los depósitos como discos duros.
Con la integración nueva, puedes copiar archivos dentro y fuera de los depósitos, cambiar sus nombres y crear directorios nuevos;  en resumen, puedes administrar los contenidos de tus depósitos de Cloud Storage directamente desde Visual Studio. Consulta la documentación para obtener información completa sobre lo que puedes hacer ahora con tus depósitos de Cloud Storage.

A continuación, se encuentra el recurso nuevo de Google Cloud Pub/Sub que agregamos a Cloud Explorer:
El nodo nuevo de Cloud Pub/Sub te permite administrar tus temas y suscripciones de Pub/Sub, y también enviar mensajes nuevos a temas existentes para pruebas, todo dentro de Visual Studio. Consulta la documentación para obtener información completa sobre lo que puedes hacer con este nodo nuevo.

Nuevos cmdlets de Powershell 


Visual Studio es un entorno realmente bueno para la mayor parte del trabajo de desarrollo, pero a veces la solución correcta es usar Powershell para automatizar tus recursos de GCP. Con este fin, hemos agregado cmdlets nuevos para administrar aún más recursos. Agregamos cmdlets para interactuar con BigQuery, lo cual te permite ejecutar consultas, crear tablas y hacer otras tareas. También agregamos cmdlets para administrar clústeres y nodos de Google Container Engine.

Kubernetes, y su variante administrada por GCP de Google Container Engine, se está convirtiendo en uno de los métodos más populares para administrar las cargas de trabajo en la nube. Es por ello que agregamos un conjunto de cmdlets para administrar los clústeres de tu Container Engine desde Powershell. Por ejemplo, usa los siguientes comandos para crear un clúster nuevo.
# Creates a Container Engine Node Config with image type CONTAINER_VM
# and 20 GB disk size for each node.
$nodeConfig = New-GkeNodeConfig -DiskSizeGb 20 `
                                -ImageType CONTAINER_VM

# Creates a cluster named "my-cluster" in the default zone of the
# default project using config $nodeConfig and network "my-network".
Add-GkeCluster -NodeConfig $nodeConfig `
               -ClusterName "my-cluster" `
               -Network "my-network"

Para obtener más información sobre lo que puedes hacer con los cmdlets de Container Engine, consulta la documentación

También existe BigQuery, una gran solución de almacenamiento de datos que se usa para guardar miles de millones de filas y realiza consultas para extraer estadísticas de todos esos datos. Aquí también hay nuevos cmdlets para administrar BigQuery directamente desde Powershell. Por ejemplo, aquí se muestra la manera de crear una tabla nueva de BigQuery:
# Creates a schema object to be used in multiple tables.
$schema = New-BqSchema "Page" "STRING" | New-BqSchema "Referrer" "STRING" |
    New-BqSchema "Timestamp" "DATETIME" | Set-BqSchema

# Creates a new table with the Schema object from above.
$table = $dataset | New-BqTable "logs2014" -Schema $schema
Para obtener más información sobre lo que puedes hacer con los cmdlets de BigQuery, consulta la documentación.

Queremos recibir sus comentarios 


Deseamos trabajar en las funciones que más te importan mientras continuamos mejorando las cargas de trabajo de .NET y Windows en GCP. ¡Continúa enviándonos tus comentarios! Puedes abrir asuntos relacionados con Cloud Tools para Visual Studio y Cloud Tools para Powershell en sus repositorios de Github.

Publicado por el equipo de TensorFlow
En TensorFlow 1.3 se introducen dos funciones importantes que te recomendamos probar:
  • Conjuntos de datos: una forma completamente nueva de crear procesos de entrada (es decir, lectura de datos para tu programa).
 Publicado por el equipo de TensorFlow
En TensorFlow 1.3 se introducen dos funciones importantes que te recomendamos probar:
  • Conjuntos de datos: una forma completamente nueva de crear procesos de entrada (es decir, lectura de datos para tu programa).
  • Estimadores: un método de alto nivel para crear modelos de TensorFlow. Los estimadores incluyen modelos preconfigurados para tareas comunes de aprendizaje automático, pero también puedes usarlos para crear tus propios modelos personalizados.

A continuación, te mostramos cómo se adecuan a la arquitectura de TensorFlow. Juntos ofrecen una forma sencilla de crear modelos de TensorFlow y enviarles datos:

Nuestro modelo de ejemplo


Para explorar estas funciones, compilaremos un modelo y te mostraremos fragmentos de código importantes. El código completo está disponible aquí y se incluyen instrucciones para obtener los archivos de capacitación y prueba. Ten en cuenta que el código se escribió para demostrar la funcionalidad de los conjuntos de datos y los estimadores, pero no se optimizó para brindar el máximo rendimiento.

El modelo entrenado categoriza las flores de iris en función de cuatro características botánicas (longitud del sépalo, ancho del sépalo, longitud del pétalo y ancho del pétalo). Por lo tanto, durante la inferencia, puedes proporcionar valores para esas cuatro características y el modelo predecirá que la flor corresponde a una de las tres hermosas variedades siguientes:
De izquierda a derecha: Iris setosa (por Radomil, CC BY-SA 3.0), iris versicolor (por Dlanglois, CC BY-SA 3.0) e iris virginica(por Frank Mayfield, CC BY-SA 2.0).

Prepararemos un clasificador de red neuronal profunda con la estructura que se indica a continuación. Todos los valores de entrada y salida serán float32, y la suma de los valores de salida será igual a 1 (ya que se predice la probabilidad para cada tipo de iris individual):

Por ejemplo, un resultado de salida podría ser 0,05 para iris setosa, 0,9 para iris versicolor y 0,05 para iris virginica, lo cual indica un 90% de probabilidad de que se trate de una iris versicolor.

¡Muy bien! Ahora que definimos el modelo, veamos cómo podemos usar conjuntos de datos y estimadores para prepararlo y realizar predicciones.

Introducción a los conjuntos de datos


Los conjuntos de datos son una nueva manera de crear procesos de entrada para modelos de TensorFlow. Esta API ofrece un rendimiento muy superior al que se obtiene usando feed_dict o los procesos basados en cola, y es más limpia y fácil de usar. Si bien la Datasets API todavía reside en tf.contrib.data en la versión 1.3, prevemos que pase a ser central en la versión 1.4, por lo que este es el mejor momento para probarla.

A grandes rasgos, Datasets API está compuesta por las siguientes clases:

Donde:
  • Dataset: clase básica que contiene los métodos para crear y transformar conjuntos de datos. También te permite inicializar un conjunto de datos a partir de datos en la memoria, o de un generador Python.
  • TextLineDataset: lee líneas de archivos de texto.
  • TFRecordDataset: lee registros de archivos TFRecord.
  • FixedLengthRecordDataset: lee registros de tamaño fijo de archivos binarios.
  • Iterator: proporciona una forma de acceder a un elemento del conjunto de datos a la vez.

Nuestro conjunto de datos


Para comenzar, observemos el conjunto de datos que emplearemos en nuestro modelo. Leeremos datos de un archivo CSV, donde cada fila contendrá cinco valores (los cuatro valores de entrada y la etiqueta):

La etiqueta será la siguiente:
  • 0 para iris setosa;
  • 1 para versicolor;
  • 2 para virginica.

Representación de nuestro conjunto de datos


Para describir nuestro conjunto de datos, primero crearemos una lista de nuestras funciones:
feature_names = [
    'SepalLength',
    'SepalWidth',
    'PetalLength',
    'PetalWidth']

Cuando preparemos nuestro modelo, necesitaremos una función que lea el archivo de entrada y muestre los datos de la función y la etiqueta. La Estimators API exige la creación una función con el siguiente formato:
def input_fn():
    ...<code>...
    return ({ 'SepalLength':[values], ..<etc>.., 'PetalWidth':[values] },
            [IrisFlowerType])

El valor que se muestra debe ser una tupla de dos elementos organizada de la siguiente manera:
  • El primero debe ser un elemento dict en el que cada función de entrada sea una clave y luego una lista de valores para el lote de preparación.
  • El segundo elemento es una lista de etiquetas para el lote de preparación.

Debido a que mostraremos un lote de funciones de entrada y etiquetas de preparación, todas las listas de la instrucción return tendrán la misma extensión. En términos técnicos, siempre que mencionamos una “lista” en realidad nos referimos a un tensor TensorFlow 1-d.

Para permitir la reutilización simple de input_fn, le agregaremos algunos argumentos. Esto nos permite compilar funciones de entrada con diferentes configuraciones. Los argumentos son bastante simples:
  • file_path: indica el archivo de datos que se leerá.
  • perform_shuffle: indica si se debe aleatorizar el orden de los registros.
  • repeat_count: indica la cantidad de veces que se deben iterar los registros del conjunto de datos. Si se especifica 1, por ejemplo, cada registro se leerá una vez. Si se especifica None, la iteración continuará sin detenerse.

Aquí te mostramos la manera de implementar esta función usando la Dataset API. Integraremos esto en una “función de entrada” que resulte adecuada cuando agreguemos datos a nuestro modelo de estimador, más adelante:
def my_input_fn(file_path, perform_shuffle=False, repeat_count=1):
   def decode_csv(line):
       parsed_line = tf.decode_csv(line, [[0.], [0.], [0.], [0.], [0]])
       label = parsed_line[-1:] # Last element is the label
       del parsed_line[-1] # Delete last element
       features = parsed_line # Everything (but last element) are the features
       d = dict(zip(feature_names, features)), label
       return d

   dataset = (tf.contrib.data.TextLineDataset(file_path) # Read text file
       .skip(1) # Skip header row
       .map(decode_csv)) # Transform each elem by applying decode_csv fn
   if perform_shuffle:
       # Randomizes input using a window of 256 elements (read into memory)
       dataset = dataset.shuffle(buffer_size=256)
   dataset = dataset.repeat(repeat_count) # Repeats dataset this # times
   dataset = dataset.batch(32)  # Batch size to use
   iterator = dataset.make_one_shot_iterator()
   batch_features, batch_labels = iterator.get_next()
   return batch_features, batch_labels

Ten en cuenta lo siguiente:
  • TextLineDataset: La Dataset API realizará por ti un enorme trabajo de administración de memoria cuando uses sus conjuntos de datos basados en archivos. Por ejemplo, puedes leer archivos del conjunto de datos mucho más grandes que la memoria o leer varios archivos especificando una lista como argumento.
  • shuffle: lee registros buffer_size y luego cambia (aleatoriza) el orden de estos.
  • map: llama a la función decode_csv con cada elemento del conjunto de datos como argumento (debido a que usaremos TextLineDataset, cada elemento será una línea de texto CSV). Luego, aplicaremos decode_csv a cada una de las líneas.
  • decode_csv: divide cada línea en campos y proporciona valores predeterminados si es necesario. Luego muestra un dict con las claves y los valores de campo. La función de mapa actualiza cada elemento (línea) del conjunto de datos con el dict.

Esta fue una introducción a los conjuntos de datos. Solo por diversión, ahora podemos usar esta función para imprimir el primer lote:
next_batch = my_input_fn(FILE, True) # Will return 32 random elements

# Now let's try it out, retrieving and printing one batch of data.
# Although this code looks strange, you don't need to understand
# the details.
with tf.Session() as sess:
    first_batch = sess.run(next_batch)
print(first_batch)

# Output
({'SepalLength': array([ 5.4000001, ...<repeat to 32 elems>], dtype=float32),
  'PetalWidth': array([ 0.40000001, ...<repeat to 32 elems>], dtype=float32),
  ...
 },
 [array([[2], ...<repeat to 32 elems>], dtype=int32) # Labels
)

Eso es todo lo que necesitamos de la Dataset API para implementar nuestro modelo. No obstante, los conjuntos de datos ofrecen muchas más capacidades. Observa la sección final de esta publicación, donde hemos recopilado más recursos.

Introducción a los estimadores


La Estimators API es una API de alto nivel que reduce notablemente el código estándar que antes necesitabas escribir cuando preparabas un modelo de TensorFlow. Los estimadores también son muy flexibles y te permiten anular el comportamiento predeterminado si tu modelo tiene requisitos específicos.

Existen dos formas de compilar tu modelo usando la Estimators API:
  • Estimadores preconfigurados: son estimadores predefinidos, creados para generar un tipo de modelo específico. En esta entrada de blog, usaremos el estimador preconfigurado DNNClassifier.
  • Estimator (clase básica): te permite controlar por completo el método de creación de tu modelo usando una función model_fn. En otra entrada del blog trataremos la manera de hacer esto.

A continuación, te mostramos el diagrama de clases para los estimadores:

Prevemos agregar más estimadores preconfigurados en futuras versiones.

Como puedes ver, todos los estimadores usan input_fn, que proporciona datos de entrada al estimador. En nuestro caso, reutilizaremos la función my_input_fn que definimos para este fin.

El siguiente código crea una instancia del estimador que predice el tipo de flor iris:
# Create the feature_columns, which specifies the input to our model.
# All our input features are numeric, so use numeric_column for each one.
feature_columns = [tf.feature_column.numeric_column(k) for k in feature_names]

# Create a deep neural network regression classifier.
# Use the DNNClassifier pre-made estimator
classifier = tf.estimator.DNNClassifier(
   feature_columns=feature_columns, # The input features to our model
   hidden_units=[10, 10], # Two layers, each with 10 neurons
   n_classes=3,
   model_dir=PATH) # Path to where checkpoints etc are stored

Ahora tenemos un estimador que podemos empezar a preparar.

Preparación del modelo


La preparación se realiza usando una sola línea de código de TensorFlow:
# Train our model, use the previously function my_input_fn
# Input to training is a file with training example
# Stop training after 8 iterations of train data (epochs)
classifier.train(
   input_fn=lambda: my_input_fn(FILE_TRAIN, True, 8))

Aguarda... ¿Qué es “lambda: my_input_fn(FILE_TRAIN, True, 8)”? Es el espacio en el que vinculamos conjuntos de datos con estimadores. Los estimadores necesitan datos para la preparación, evaluación y predicción, y usan input_fn para obtener los datos. Los estimadores requieren una función input_fn sin argumentos, por lo que crearemos una función sin argumentos usando lambda, que llama a nuestra función input_fn con los argumentos deseados: file_path, shuffle setting, y repeat_count. En nuestro caso, usamos nuestra función my_input_fn, y le pasamos lo siguiente:
  • FILE_TRAIN, que es el archivo de datos de preparación.
  • True, que indica al estimador cambiar el orden de los datos.
  • 8, que indica al estimador reproducir y repetir el conjunto de datos 8 veces.

Evaluación del modelo preparado


Ya tenemos un modelo preparado. ¿Cómo podemos evaluar su funcionamiento? Por suerte, todos los estimadores tienen un método evaluate:
# Evaluate our model using the examples contained in FILE_TEST
# Return value will contain evaluation_metrics such as: loss & average_loss
evaluate_result = estimator.evaluate(
   input_fn=lambda: my_input_fn(FILE_TEST, False, 4)
print("Evaluation results")
for key in evaluate_result:
   print("   {}, was: {}".format(key, evaluate_result[key]))

En nuestro caso, alcanzamos una precisión que ronda el 93%. Por supuesto, existen varias formas de mejorar esa precisión. Una consiste simplemente en ejecutar el programa de forma repetida. Debido a que el estado del modelo es persistente (en model_dir=PATH más arriba), este mejorará a medida que lo prepares con más iteraciones, hasta estabilizarse. Otra forma consiste en ajustar la cantidad de capas ocultas o de nodos de cada capa oculta. Haz experimentos con esto libremente, pero ten en cuenta que al realizar un cambio debes eliminar el directorio especificado en model_dir=PATH, ya que modificarás la estructura de DNNClassifier.

Realización de predicciones con el modelo preparado


¡Eso es todo! Ya tenemos un modelo preparado, y si los resultados de la evaluación son satisfactorios, podemos usarla para predecir una flor de iris en función de algunos datos. Tanto en la preparación como en la evaluación, realizamos predicciones usando una llamada a una función individual:
# Predict the type of some Iris flowers.
# Let's predict the examples in FILE_TEST, repeat only once.
predict_results = classifier.predict(
    input_fn=lambda: my_input_fn(FILE_TEST, False, 1))
print("Predictions on test file")
for prediction in predict_results:
   # Will print the predicted class, i.e: 0, 1, or 2 if the prediction
   # is Iris Sentosa, Vericolor, Virginica, respectively.
   print prediction["class_ids"][0] 

Realización de predicciones sobre datos de la memoria


En el código anterior se especificó FILE_TEST para realizar predicciones sobre datos guardados en un archivo, pero ¿cómo podríamos realizar predicciones en función de datos que residen en otras fuentes, como la memoria? Como podrás suponer, para esto no es necesario modificar nuestra llamada a predict. En lugar de ello, configuraremos la Dataset API para usar una estructura de memoria como se muestra a continuación:
# Let create a memory dataset for prediction.
# We've taken the first 3 examples in FILE_TEST.
prediction_input = [[5.9, 3.0, 4.2, 1.5],  # -> 1, Iris Versicolor
                    [6.9, 3.1, 5.4, 2.1],  # -> 2, Iris Virginica
                    [5.1, 3.3, 1.7, 0.5]]  # -> 0, Iris Sentosa
def new_input_fn():
   def decode(x):
       x = tf.split(x, 4) # Need to split into our 4 features
       # When predicting, we don't need (or have) any labels
       return dict(zip(feature_names, x)) # Then build a dict from them

   # The from_tensor_slices function will use a memory structure as input
   dataset = tf.contrib.data.Dataset.from_tensor_slices(prediction_input)
   dataset = dataset.map(decode)
   iterator = dataset.make_one_shot_iterator()
   next_feature_batch = iterator.get_next()
   return next_feature_batch, None # In prediction, we have no labels

# Predict all our prediction_input
predict_results = classifier.predict(input_fn=new_input_fn)

# Print results
print("Predictions on memory data")
for idx, prediction in enumerate(predict_results):
   type = prediction["class_ids"][0] # Get the predicted class (index)
   if type == 0:
       print("I think: {}, is Iris Sentosa".format(prediction_input[idx]))
   elif type == 1:
       print("I think: {}, is Iris Versicolor".format(prediction_input[idx]))
   else:
       print("I think: {}, is Iris Virginica".format(prediction_input[idx])

Dataset.from_tensor_slides() se designa para conjuntos de datos pequeños que entran en la memoria. Cuando usas TextLineDataset, como lo hicimos para el entrenamiento y la evaluación, puedes tener archivos arbitrariamente grandes siempre que tu memoria pueda administrar el búfer de orden aleatorio y los tamaños de los lotes.

Hay más


Usar un estimador preconfigurado como DNNClassifier aporta mucho valor. Además de ser fáciles de usar, los estimadores preconfigurados proporcionan métricas de evaluación integradas y crean resúmenes que puedes ver en TensorBoard. Para ver este informe, inicia TensorBoard desde tu línea de comandos de la siguiente manera:
# Replace PATH with the actual path passed as model_dir argument when the
# DNNRegressor estimator was created.
tensorboard --logdir=PATH 

En los siguientes diagramas se muestran algunos de los datos que proporcionará TensorBoard:

Resumen


En esta entrada de blog, exploramos conjuntos de datos y estimadores. Son API importantes para definir el flujo de datos de entrada y crear modelos, por lo que vale la pena dedicar tiempo a aprenderlas.

Para obtener más información, asegúrate de observar lo siguiente:

Esto no termina aquí. En poco tiempo, publicaremos más entradas de blog en las que describiremos cómo funcionan esas API. ¡Permanece atento!

Hasta entonces, ¡feliz codificación con TensorFlow!

Publicado por Sarah Clark, administradora del programa, capacitación de desarrolladores web
Si te dedicas al desarrollo web, la oferta abunda en el mercado y probablemente te convenga distinguirte de los demás desarrolladores. ¿Te gustaría mostrar que tienes las capacidades necesarias para crear aplicaciones web receptivas y flexibles?
 Publicado por Sarah Clark, administradora del programa, capacitación de desarrolladores web
Si te dedicas al desarrollo web, la oferta abunda en el mercado y probablemente te convenga distinguirte de los demás desarrolladores. ¿Te gustaría mostrar que tienes las capacidades necesarias para crear aplicaciones web receptivas y flexibles?
El equipo de certificaciones Google Developers tiene el agrado de anunciar la certificación Mobile Web Specialist. Con esta certificación nueva, basada en un análisis exhaustivo del mercado, se destaca a los desarrolladores que tienen habilidades con más demanda, como los desarrolladores de contenido web móvil. (No te preocupes, las habilidades demostradas en este examen se pueden aplicar a equipos de escritorio y a todos los navegadores).
Usa nuestra Guía de estudio para especialistas en Web móvil como referencia en la preparación. Cuando estés listo para la evaluación, deberás escribir código y el examen será cronometrado y se basará en el desempeño. El costo para intentar acceder a la certificación es de USD 99 USD (6500 INR si resides en la India) e incluye hasta tres intentos de examen.
Mira este video corto para ver un panorama rápido del proceso de certificación Mobile Web Specialist:
Al obtener la certificación Mobile Web Specialist se te otorga una insignia digital que puedes mostrar en tu currículum y en perfiles de redes sociales. Como miembro de la comunidad de ex alumnos con certificación Mobile Web Specialist, también tendrás acceso a beneficios del programa centrados en aumentar tu visibilidad como un desarrollador certificado.
La certificación Mobile Web Specialist se suma a la certificación Associate Android Developer de la familia de certificaciones basadas en el desempeño de Google.
Visita g.co/dev/mobile-web-cert para comenzar y obtener tu certificación Mobile Web Specialist de Google.

Publicado por Roy Glasberg, director mundial, Programa Launchpad y Launchpad Accelerator
Launchpad Accelerator nos da la oportunidad de trabajar con programadores excelentes que están superando desafíos importantes en todo el mundo y de brindarles capacitación, ya sea mediante la modernización del ...
 Publicado por Roy Glasberg, director mundial, Programa Launchpad y Launchpad Accelerator
Launchpad Accelerator nos da la oportunidad de trabajar con programadores excelentes que están superando desafíos importantes en todo el mundo y de brindarles capacitación, ya sea mediante la modernización del comercio digital en todo África, la provisión de acceso a herramientas multimedia que respaldan la educación para personas con necesidades especiales o el uso de IA para simplificar operaciones comerciales.

Por eso, redoblaremos esfuerzos y abriremos las inscripciones para la próxima clase del programa a más países por primera vez, a partir de hoy. Esta es la lista completa de los nuevos países añadidos:
  • África: Argelia, Egipto, Gana, Marruecos, Tanzania, Tunes y Uganda
  • Asia: Bangladesh, Myanmar, Paquistán y Sri Lanka
  • Europa: Estonia, Rumania, Ucrania, Belarús y Rusia
  • Latinoamérica: Costo Rica, Panamá, Perú y Uruguay

Estos países se suman a la lista más amplia de países que ya forman parte del programa, entre los que se incluyen: Argentina, Brasil, Chile, Colombia, República Checa, Hungría, la India, Indonesia, Kenia, Malasia, México, Nigeria, Filipinas, Polonia, Sudáfrica, Tailandia y Vietnam.

El proceso de inscripción para el programa gratuito finalizará el 2 de octubre de 2017 a las 9 a. m. PST. Más adelante, durante el año, se invitará a los programadores seleccionados de la lista al espacio de Google Developers Launchpad en San Francisco para que disfruten de 2 semanas de capacitación con todos los gastos pagos.

¿Cuáles son los beneficios?


La capacitación en la sede central de Google incluye instrucción intensiva que otorgarán más de 20 equipos de Google, instructores expertos de las empresas de tecnología más importantes y miembros de la industria de capital de riesgo de Silicon Valley. Los participantes recibirán instrucción sin cargo, créditos para productos Google y asistencia de relaciones públicas, y continuarán trabajando en colaboración estrecha con Google cuando regresen a sus países durante el programa de 6 meses. Conoce las experiencias de otros estudiantes aquí.

¿Qué buscamos cuando seleccionamos startups?


Cada startup que se inscribe al Launchpad Accelerator se considera de forma holística y con sumo cuidado. A continuación, se muestran las reglas generales de nuestro proceso, para que comprendas lo que esperamos de los candidatos.

Todas las startups del programa deben cumplir con los siguientes requisitos:
  • Deben ser startups tecnológicas.
  • Deben apuntar a sus mercados locales.
  • Deben tener una adaptación del producto al mercado comprobada (más allá de la etapa de ideación).
  • Deben tener sus sedes en los países antes mencionados.

Además, estamos interesados en saber la clasificación de las startups en cuestión. También consideramos lo siguiente:
  • El problema que se intenta resolver. ¿De qué forma se crea valor para los usuarios? ¿Cómo se enfrenta un desafío real para la ciudad, el país o la región de origen?
  • ¿Tiene el equipo de gestión una actitud de liderazgo y el impulso necesario para convertirse en una influencia?
  • ¿Se compartirá lo aprendido en Silicon Valley para beneficio de otras startups en el entorno local?
  • Si tu país no figura en la lista, no te pierdas las actualizaciones. Esperamos continuar sumando países al programa en el futuro.

Queremos conocer tu opinión y evaluar la manera en que podemos trabajar juntos para mejorar tu empresa.
Participantes de la Clase 4



Una función de seguridad clave para programadores y administradores de aplicaciones es la posibilidad de permitir o rechazar solicitudes entrantes en función de las direcciones IP de origen. Esta capacidad puede ayudarte a realizar pruebas de producción sin exponer tu app al mundo, bloquear el acceso a tu app desde ubicaciones específicas o bloquear solicitudes de un usuario malintencionado.


Una función de seguridad clave para programadores y administradores de aplicaciones es la posibilidad de permitir o rechazar solicitudes entrantes en función de las direcciones IP de origen. Esta capacidad puede ayudarte a realizar pruebas de producción sin exponer tu app al mundo, bloquear el acceso a tu app desde ubicaciones específicas o bloquear solicitudes de un usuario malintencionado.

Hoy, nos entusiasma anunciar la versión beta del firewall de Google App Engine. Con el firewall de App Engine, solo debes proporcionar un conjunto de reglas, ordenarlas por prioridad y especificar una dirección IP, o un conjunto de direcciones IP, para bloquear o permitir, y nosotros nos ocupamos del resto.

Cuando el firewall de App Engine recibe una solicitud que configuraste para que se rechace, muestra una respuesta HTTP 403 Forbidden sin siquiera alcanzar tu app. Si tu app está inactiva, se evitará la ejecución de nuevas instancias, y si recibes mucho tráfico, la solicitud rechazada no agregará carga ni te costará dinero.

El firewall de App Engine reemplaza la necesidad de una solución basada en código dentro de tu app que permite el ingreso de solicitudes, pero que puede costarte recursos y exponer tu app.


Primeros pasos con el firewall de App Engine 


Puedes configurar las reglas del firewall de App Engine en Google Cloud Console, en la App Engine Admin API o en la herramienta de línea de comandos de gcloud.

Imaginemos que deseas probar tu aplicación y permitir el acceso únicamente a navegadores de la red privada de tu empresa. Abre tus reglas de firewall en Cloud Console. Verás una regla predeterminada que habilita todo el tráfico hacia tu app.

Primero, agrega una regla nueva que permita tráfico solo del rango de direcciones IP que provengan de tu red privada. Luego, actualiza la regla predeterminada para rechazar todo el tráfico.


Como en el caso de la semántica típica del firewall, el firewall de App Engine evalúa primero las reglas con un valor de prioridad más bajo y luego las reglas con valores más altos. En el ejemplo anterior, primero se evalúa la regla de permiso con un valor de prioridad de 100 y luego la regla predeterminada.

Para asegurarte de que tu conjunto de reglas del firewall funcionen de la forma prevista, puedes probar una dirección IP para ver si una solicitud que proviene de esa dirección se permitiría o se rechazaría.

En Cloud Console, haz clic en la pestaña Test IP de la sección Firewall Rules.

La respuesta indica si la solicitud puede continuar y señala la regla específica del firewall que vinculó la dirección IP proporcionada.
Con el firewall de App Engine es fácil configurar el acceso a la red para tu app y concentrarte en lo más importante, tu app, sin preocuparte por el control del acceso en tu código. Consulta la documentación completa aquí.

El firewall de App Engine está disponible en versión beta; por ello, debes evitar usar esta funcionalidad en entornos de producción. Si tienes preguntas o inquietudes, o si algo no funciona como esperabas, puedes realizar una publicación en el foro de Google App Engine, registrar un problema público o comunicarte a través del canal de App Engine en Slack (#app-engine).

Publicado por Takeshi Hagikura, ingeniero de programas para programadores
Desde el anuncio de ConstraintLayout en Google I/O, el año pasado, hemos continuado mejorando la estabilidad del diseño y la compatibilidad del editor de diseño. También agregamos nuevas funciones específicas de ...
 Publicado por Takeshi Hagikura, ingeniero de programas para programadores
Desde el anuncio de ConstraintLayout en Google I/O, el año pasado, hemos continuado mejorando la estabilidad del diseño y la compatibilidad del editor de diseño. También agregamos nuevas funciones específicas de ConstraintLayout que te ayudarán a compilar varios tipos de diseños, como la introducción de cadenas y la configuración del tamaño como proporción. Además de estas funciones, obtendrás un beneficio de rendimiento importante al usar ConstraintLayout. En esta esta publicación, te mostraremos los beneficios que puedes obtener de estas mejoras de rendimiento.

¿Cómo se dibujan las vistas en Android?


Para entender mejor el funcionamiento de ConstraintLayout, demos un paso atrás y observemos la forma en que Android dibuja vistas.

Cuando un usuario invoca una vista de Android, el marco de trabajo del sistema operativo indica a la vista que se dibuje a sí misma. El proceso de dibujo incluye 3 etapas:
  1. Medición
    El sistema realiza un recorrido de arriba a abajo en el árbol de vistas para determinar el tamaño de cada ViewGroup y cada elemento View. Cuando se mide un ViewGroup, también se miden sus elementos secundarios.
  2. Diseño
    Se produce otro recorrido de arriba a abajo, y cada ViewGroup determina las posiciones de sus elementos secundarios usando los tamaños establecidos en la etapa de medición.
  3. Dibujo
    El sistema realiza otro recorrido de arriba a abajo. Para cada objeto del árbol de vistas, se crea un objeto Canvas a fin de enviar una lista de comandos de dibujo a la GPU. En estos comandos se incluyen los tamaños y las posiciones de los objetos ViewGroup y View que el sistema determinó durante las dos etapas anteriores.
Figura 1: Ejemplo de cómo en la etapa de medición se recorre un árbol de vistas.

Para cada etapa del proceso de dibujo se requiere un recorrido de arriba a abajo del árbol de vistas. Por lo tanto, cuantas más vistas incorpores dentro de cada una (o anides) en la jerarquía de vistas, más tiempo y recursos de cómputo deberá emplear el dispositivo para dibujar las vistas. Al mantener una jerarquía plana en tus diseños de apps para Android, podrás crear una interfaz de usuario rápida y receptiva para tu app.


El costo de una jerarquía de diseño tradicional


Teniendo en cuenta esa explicación, creemos una jerarquía de diseño tradicional que utilice los objetos LinearLayout y RelativeLayout.
Figura 2: Ejemplo de diseño.

Supongamos que deseamos compilar un diseño como el de la imagen anterior. Si realizas la compilación con diseños tradicionales, el archivo XML contendrá una jerarquía de elementos similar a la siguiente (para este ejemplo, omitimos los atributos):
<RelativeLayout>
  <ImageView />
  <ImageView />
  <RelativeLayout>
    <TextView />
    <LinearLayout>
      <TextView />
      <RelativeLayout>
        <EditText />
      </RelativeLayout>
    </LinearLayout>
    <LinearLayout>
      <TextView />
      <RelativeLayout>
        <EditText />
      </RelativeLayout>
    </LinearLayout>
    <TextView />
  </RelativeLayout>
  <LinearLayout >
    <Button />
    <Button />
  </LinearLayout>
</RelativeLayout>

Si bien siempre se pueden realizar mejoras en este tipo de jerarquía de vistas, seguramente deberás crear una jerarquía con algunas vistas anidadas.

Como se mencionó antes, las jerarquías anidadas pueden afectar negativamente el rendimiento. Observemos la forma en que las vistas anidadas afectan el rendimiento de la IU usando la herramienta Systrace de Android Studio. Llamamos, mediante programación, a las etapas de medición y diseño para cada ViewGroup (ConstraintLayout y RelativeLayout) y activamos Systrace mientras se ejecutan las llamadas de medición y diseño. El siguiente comando genera un archivo de información general que contiene eventos claves, como pasadas de medición y diseño de alto consumo de recursos, que ocurren durante un intervalo de 20 segundos:
python $ANDROID_HOME/platform-tools/systrace/systrace.py --time=20 -o ~/trace.html gfx view res

Para obtener información detallada sobre cómo puedes usar Systrace, consulta la guía Análisis del rendimiento de la IU con Systrace.

Systrace destaca automáticamente los (diversos) problemas de rendimiento de este diseño y te ofrece sugerencias para solucionarlos. Al hacer clic en la pestaña “Alerts”, verás que para dibujar esta jerarquía de vistas se requieren 80 pasadas de alto consumo de recursos por las fases de medición y diseño.

Activar tantas etapas de medición y diseño que consumen muchos recursos no es de ninguna manera la opción ideal. Una actividad de dibujo de tal magnitud podría provocar omisiones de fotogramas que resultarán evidentes para los usuarios. Podemos concluir que el diseño tiene un bajo rendimiento debido a la jerarquía anidada y a la característica de RelativeLayout, que mide cada uno de sus elementos secundarios dos veces.
Figura 3: Observación de las alertas de Systrace para la variante de diseño que utiliza RelativeLayout.

Puedes revisar todo el código que utilizamos para realizar estas mediciones en nuestro repositorio de GitHub.

Beneficios de un objeto ConstraintLayout


Si creas el mismo diseño usando ConstraintLayout, el archivo XML contendrá una jerarquía de elementos similar a la siguiente (nuevamente, se omiten los atributos):
<android.support.constraint.ConstraintLayout>
  <ImageView />
  <ImageView />
  <TextView />
  <EditText />
  <TextView />
  <TextView />
  <EditText />
  <Button />
  <Button />
  <TextView />
</android.support.constraint.ConstraintLayout>

Como se muestra en este ejemplo, ahora el diseño tiene una jerarquía completamente plana. Esto de sebe a que ConstraintLayout te permite compilar diseños complejos sin tener que anidar elementos View y ViewGroup.

Por ejemplo, observemos TextView y EditText en el medio del diseño:
Al usar una variante RelativeLayout, debes crear un nuevo elemento ViewGroup para alinear EditText verticalmente en TextView:
<LinearLayout
    android:id="@+id/camera_area"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_below="@id/title" >

    <TextView
        android:text="@string/camera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:id="@+id/cameraLabel"
        android:labelFor="@+id/cameraType"
        android:layout_marginStart="16dp" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/cameraType"
            android:ems="10"
            android:inputType="textPersonName"
            android:text="@string/camera_value"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginTop="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginEnd="8dp" />
    </RelativeLayout>
</LinearLayout>

En cambio, al usar ConstraintLayout, puedes lograr el mismo efecto simplemente agregando una limitación desde la referencia de TextView hasta la referencia de EditText sin crear otro elemento ViewGroup:
Figura 4: Limitación entre EditText y TextView.
<TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      app:layout_constraintLeft_creator="1"
      app:layout_constraintBaseline_creator="1"
      app:layout_constraintLeft_toLeftOf="@+id/activity_main_done"
      app:layout_constraintBaseline_toBaselineOf="@+id/cameraType" />

Al ejecutar la herramienta Systrace para la versión de nuestro diseño que usa ConstraintLayout, verás muchas menos pasadas de medición y diseño de alto consumo de recursos durante el mismo intervalo de 20 segundos. Esta mejora de rendimiento tiene sentido ahora que deseamos mantener una jerarquía de vistas plana.
Figura 5: Observación de las alertas de Systrace para la variante de diseño que utiliza ConstraintLayout.

En una nota relacionada, compilamos la variante ConstraintLayout de nuestro diseño usando solo el editor de diseño en lugar de editar el archivo XML manualmente. Para lograr el mismo efecto visual usando RelativeLayout, probablemente hubiéramos necesitado editar el archivo XML de forma manual.

Medición de la diferencia de rendimiento


Analizamos el tiempo que demora cada pasada de medición y diseño para dos tipos de diseño, ConstraintLayout y RelativeLayout, usando OnFrameMetricsAvailableListener, que se introdujo en Android 7.0 (nivel de API 24). Esta clase te permite recopilar información fotograma por fotograma sobre la representación de la IU de tu app.

Al llamar al siguiente código, puedes comenzar a grabar acciones de la IU fotograma por fotograma:
window.addOnFrameMetricsAvailableListener(
        frameMetricsAvailableListener, frameMetricsHandler);

Una vez que hay disponible información sobre el tiempo, la app activa el callback frameMetricsAvailableListener() . Puesto que nos interesa el rendimiento de la medición y el diseño, al obtener la duración real del fotograma llamamos a FrameMetrics.LAYOUT_MEASURE_DURATION.
Window.OnFrameMetricsAvailableListener {
        _, frameMetrics, _ ->
        val frameMetricsCopy = FrameMetrics(frameMetrics);
        // Layout measure duration in nanoseconds
        val layoutMeasureDurationNs = 
                frameMetricsCopy.getMetric(FrameMetrics.LAYOUT_MEASURE_DURATION);

Para obtener más información sobre los demás tipos de datos de duración que FrameMetrics puede recibir, consulta la referencia de la API FrameMetrics.

Resultados de la medición: ConstraintLayout es más rápido


Nuestra comparación de rendimiento muestra que ConstraintLayout presenta una mejora del 40% en el rendimiento respecto de RelativeLayout:
Figura 6: Medición/diseño (unidad: ms, promedio de 100 fotogramas).

Como se muestra en estos resultados, ConstraintLayout probablemente tenga un mejor rendimiento que los diseños tradicionales. Además, ConstraintLayout ofrece otras funciones que te ayudarán a compilar diseños complejos y de alto rendimiento, como se discutió en la sección beneficios de un objeto ConstraintLayout. Para obtener información detallada, consulta la guía Compilar una IU receptiva con ConstraintLayout. Te recomendamos usar ConstraintLayout en los diseños de tu app. En casi todos los casos en los que antes hubieras necesitado un diseño profundamente anidado, ConstraintLayout será tu opción de diseño de confianza para lograr un rendimiento óptimo y hacer más sencillo el uso.

Apéndice: Entorno de medición


Todas las mediciones anteriores se realizaron en el siguiente entorno.


Dispositivo Nexus 5X
Versión de Android 8.0
Versión de ConstraintLayout 1.0.2


Lo que viene


Consulta la guía para desarrolladores, la documentación de referencia de la API y el artículo sobre Medium para comprender plenamente lo que ConstraintLayout puede ofrecerte. Una vez más, gracias a todos los que compartieron comentarios y problemas durante los meses transcurridos desde el lanzamiento de nuestra versión alfa de ConstraintLayout. Nos complace haber podido lanzar a principios de este año la versión 1.0 de ConstraintLayout lista para producción. Mientras continuamos mejorando ConstraintLayout, no dejes de enviarnos comentarios a través del espacio de seguimiento de problemas de Android.



Ya está disponible Firebase Admin SDK para Go. Es el cuarto lenguaje de programación que se suma a nuestra creciente familia de Admin SDK, que ya incluye compatibilidad con Java, Python y Node.js. Los Firebase Admin SDK permiten a los programadores de aplicaciones acceder mediante programación a servicios de Firebase de entornos seguros. Complementan los SDK de cliente de Firebase, que permiten a los usuarios finales acceder a Firebase desde sus navegadores web y dispositivos móviles. En la versión inicial del Firebase Admin SDK para Go se incluyen algunas funciones de Firebase Authentication: creación de tokens personalizados y verificación de tokens de ID.


Ya está disponible Firebase Admin SDK para Go. Es el cuarto lenguaje de programación que se suma a nuestra creciente familia de Admin SDK, que ya incluye compatibilidad con Java, Python y Node.js. Los Firebase Admin SDK permiten a los programadores de aplicaciones acceder mediante programación a servicios de Firebase de entornos seguros. Complementan los SDK de cliente de Firebase, que permiten a los usuarios finales acceder a Firebase desde sus navegadores web y dispositivos móviles. En la versión inicial del Firebase Admin SDK para Go se incluyen algunas funciones de Firebase Authentication: creación de tokens personalizados y verificación de tokens de ID.

Inicialización del Admin SDK para Go


De forma similar a otros Firebase Admin SDK, el Go Admin SDK se puede inicializar con diferentes credenciales de autenticación y opciones de cliente. En el siguiente fragmento de código, se muestra la manera de inicializar el SDK usando una credencial de cuenta de servicio obtenida en la Firebase console o en la Google Cloud console:
import (
  "golang.org/x/net/context"

  firebase "firebase.google.com/go"
  "google.golang.org/api/option"
)

opt := option.WithCredentialsFile("path/to/key.json")
app, err := firebase.NewApp(context.Background(), nil, opt)

Si ejecutas tu código mediante infraestructura de Google, como Google App Engine o Google Compute Engine, el SDK puede detectar automáticamente las credenciales predeterminadas de la aplicación en el entorno. En este caso, no necesitas especificar explícitamente ninguna credencial al inicializar el Go Admin SDK:
import (
  "golang.org/x/net/context"

  firebase "firebase.google.com/go"
)

app, err := firebase.NewApp(context.Background(), nil)

Creación de tokens personalizados y verificación de tokens de ID


La versión inicial de Firebase Admin SDK para Go permite crear tokens personalizados y verificar tokens de ID para Firebase. La creación de tokens personalizados te permite autenticar usuarios usando tu propio mecanismo de autenticación o almacenamiento de usuarios:
client, err := app.Auth()
if err != nil {
  return err
}

claims := map[string]interface{}{
  "premium": true,
  "package": "gold",
}
token, err := client.CustomToken("some-uid", claims)

El token personalizado que se genera puede enviarse a un dispositivo de cliente, donde se puede usar para iniciar un flujo de autenticación con un SDK de cliente de Firebase. Por otro lado, la verificación con token de ID facilita la identificación segura del usuario cuya sesión se encuentra activa en tu servidor:
client, err := app.Auth()
if err != nil {
  return err
}

decoded, err := client.VerifyIDToken(idToken)
uid := decoded.UID

Para obtener más información sobre el uso del Firebase Admin SDK para Go, consulta nuestra guía de configuración de Admin SDK.

Lo que viene


Tenemos pensado expandir aún más las capacidades del Go Admin SDK implementando otras API útiles, como la administración de usuarios y Firebase Cloud Messaging. Este SDK también es de código abierto. Por lo tanto, te invitamos a que explores nuestro repositorio de Github y participes en el proceso de desarrollo notificando problemas y enviando solicitudes de incorporación de cambios. A todos los “Golang gophers”, ¡feliz codificación con Firebase!



Cuando anunciamos la disponibilidad general de Google Stackdriver, nuestro conjunto de supervisión, registro y diagnóstico integrado para aplicaciones que se ejecutan en la nube, observamos un gran entusiasmo en nuestra comunidad de usuarios y también recibimos comentarios reveladores ...


Cuando anunciamos la disponibilidad general de Google Stackdriver, nuestro conjunto de supervisión, registro y diagnóstico integrado para aplicaciones que se ejecutan en la nube, observamos un gran entusiasmo en nuestra comunidad de usuarios y también recibimos comentarios reveladores:
  • Análisis: las métricas basadas en registros son geniales, pero desearías poder extraer también etiquetas y valores de los registros. 
  • Exportación: te agrada mucho poder exportar registros fácilmente, pero es difícil administrarlos entre cientos de proyectos. 
  • Controles: agregar todos los registros en una sola ubicación y exportarlos a varios destinos es genial, pero deseas poder determinar los registros que van a Stackdriver Logging. 
  • Precio: deseas aumentar el espacio con Stackdriver sin preocuparte demasiado por el costo de registrar todos esos datos. 
Te escuchamos; por eso hoy anunciamos varias actualizaciones para Stackdriver y nuevos precios, a fin de ofrecerte la flexibilidad que necesitas para expandirte y crecer.

A continuación, te informamos más sobre lo que viene.

Análisis simplificado con métricas basadas en registros 

Stackdriver se creó con el concepto de que al unir varias señales de registros, métricas, seguimientos y errores se puede proporcionar una mejor estadística que con cualquier señal individual. Las métricas basadas en registros son un ejemplo excelente. Por eso las métricas nuevas y mejoradas basadas en registros son:
  • Más rápidas: redujimos el tiempo que transcurre desde que una entrada de registro ingresa hasta que se refleja en una métrica basada en registros de cinco minutos a menos de uno. 
  • Más fáciles de administrar: ahora puedes extraer etiquetas definidas por los usuarios del texto de los registros. En lugar de crear una nueva métrica basada en registros para cada valor posible, puedes usar un campo en la entrada de registro como una etiqueta. 
  • Más potentes: puedes extraer valores de los registros y convertirlos en métricas de distribución. Esto te permite representar de forma eficiente muchos puntos de datos en cada momento. Stackdriver Monitoring luego puede visualizar esas métricas como un mapa de calor o por percentil. 
En el ejemplo anterior se muestra un mapa de calor producido a partir de una métrica de distribución extraída de un campo de texto en las entradas de registro.

Tony Li, Ingeniero de confiabilidad en planta del New York Times, explica cómo se usan las nuevas etiquetas definidas por los usuarios aplicadas a proxies para mejorar la confiabilidad y el rendimiento a partir de registros.
“Con las métricas basadas en registros, podemos supervisar errores que ocurren en varios proxies y visualizar la frecuencia según el momento en que ocurren para determinar regresiones o configuraciones erróneas”.
El proceso más rápido se aplica a todas las métricas basadas en registros, incluidas las que se basan en recuentos y están disponibles en general. Las métricas de distribución y las etiquetas de usuario ahora están disponibles en versión beta.


Administra los registros de tu organización con exportaciones agregadas 


Stackdriver Logging te permite exportar registros a GCS, PubSub o BigQuery usando receptores de registros. Escuchamos comentarios sobre el hecho de que la administración de exportaciones entre cientos o miles de proyectos en una organización puede resultar tediosa y estar sujeta a errores. Por ejemplo, si un administrador de seguridad de una organización quisiera exportar todos los registros de auditoría a un proyecto central en BigQuery, debería configurar un receptor de registros en cada proyecto y validar la presencia de un receptor activo para cada proyecto nuevo.

Con las exportaciones agregadas, los administradores de una organización o una carpeta pueden configurar receptores una sola vez, y estos son heredados por todos los proyectos secundarios y las subcarpetas. Esto permite que el administrador de seguridad exporte todos los registros de auditoría de su organización a BigQuery con un solo comando:

gcloud beta logging sinks create my-bq-sink 
bigquery.googleapis.com/projects/my-project/datasets/my_dataset 
--log-filter='logName= "logs/cloudaudit.googleapis.com%2Factivity"' 
--organization=1234 --include-children

Las exportaciones agregadas ayudan a garantizar que en futuros proyectos los registros se exporten correctamente. Debido a que el receptor se configura en el nivel de organización o carpetas, también evita que un propietario de un proyecto individual lo desactive.

Controla el proceso en Stackdriver Logging con filtros de exclusión 

Todos los registros que se envían a la Logging API, independientemente de que los envíes tú o los servicios de Google Cloud, siempre han ido a parar a Stackdriver Logging, donde pueden buscarse en el Visor de registros. Sin embargo, recibimos comentarios en los cuales se afirmaba que los usuarios deseaban más control sobre los registros que se transfieren a Stackdriver Logging, y los tuvimos en cuenta. Para abordar esto, los filtros de exclusión ya están disponibles en la versión beta. Los filtros de exclusión te permiten reducir costos, mejorar la relación señal/ruido al disminuir la cantidad de registros con exceso de intercambio de información y administrar el cumplimiento bloqueando los registros de una fuente o estableciendo coincidencias con un patrón por la disponibilidad en Stackdriver Logging. La nueva página Resource Usage te permite visualizar los recursos que envían registros y los que se excluyen de Stackdriver Logging.


Esto facilita la exclusión de algunos o todos los registros futuros de un recurso específico. En el ejemplo anterior, excluimos el 99% de los registros exitosos del balanceador de cargas. Sabemos que la elección y la libertad de elegir cualquier solución son importantes, por lo que todos los registros GCP están disponibles, independientemente de los filtros de exclusión de registros, para la exportación a BigQuery, Google Cloud Storage o cualquier herramienta de terceros a través de PubSub. Además, Stackdriver no aplicará tarifas por esta exportación, aunque BigQuery, GCS y PubSub sí lo harán.

A partir del 1 de diciembre, Stackdriver Logging ofrecerá 50 GB de registros por proyecto por mes gratis 


Nos comunicaron el deseo de aumentar el espacio con Stackdriver sin preocuparse por el costo de registrar todos esos datos; por eso, a partir del 1 de diciembre, aumentaremos la asignación de registros gratuitos a un límite líder en la industria de 50 GB por proyecto por mes. Este incremento apunta a acercar la potencia de las capacidades de búsqueda, almacenamiento, análisis y alerta de Stackdriver Logging a todos nuestros clientes.

¿Necesitas para tus registros una capacidad superior a la asignación mensual gratuita de 50 GB? Puedes registrarte en el nivel Premium de Stackdriver o en el excedente de registros en el nivel Básico. Después del 1 de diciembre, los registros adicionales tendrán una tarifa plana de USD 0,50/GB.


Los registros de auditoría todavía son gratuitos y están disponibles por 13 meses 

También exceptuaremos los registros de auditoría de actividad administrativa de los límites y el excedente. Estarán completamente disponibles en Stackdriver sin cargo. Ahora podrás conservarlos por 13 meses en lugar de 30 días.

Sigamos conversando 


Esperamos acercar la potencia de las capacidades de búsqueda, almacenamiento, análisis y alerta de Stackdriver Logging a todos nuestros clientes. Tenemos pensadas muchas más funciones increíbles, entre las cuales se incluyen un selector de intervalo que se lanzará en septiembre para facilitar la visibilidad de la periodicidad de los resultados de las búsquedas. Siempre esperamos más comentarios y sugerencias sobre cómo mejorar Stackdriver Logging. No dejes de enviarnos tus preguntas y comentarios.

¿Te gustaría recibir más información sobre estas nuevas funciones?



En las partes 1 y 2 de esta serie, te mostramos cómo compilar una app de guía turística conversacional con API.AI y Machine Learning API de Google Cloud. En esta parte final, aprenderás a extender esta app a los dispositivos compatibles con el Asistente de Google (Google Home, algunos teléfonos Android y iPhone, y Android Wear). También compilaremos esto sobre el agente API.AI existente que se creó en las partes 1 y 2.


En las partes 1 y 2 de esta serie, te mostramos cómo compilar una app de guía turística conversacional con API.AI y Machine Learning API de Google Cloud. En esta parte final, aprenderás a extender esta app a los dispositivos compatibles con el Asistente de Google (Google Home, algunos teléfonos Android y iPhone, y Android Wear). También compilaremos esto sobre el agente API.AI existente que se creó en las partes 1 y 2.

Nuevos intents para Actions on Google

En la parte 1, tratamos las relaciones de los contextos de entrada y salida de la app.

El contexto where requiere que el usuario suba una imagen que no sea compatible con el Asistente de Google. Podemos modificar la relación contextual como se muestra a continuación.

Agregaremos tres intents nuevos: hours-no-context, ticket-no-context y map-no-context. Cada intent configurará location como contexto de salida, de modo que otros intents puedan usar la ubicación como un parámetro de entrada. 


Habilitar la integración de Actions on Google 


Ahora habilitaremos Actions on Google para que admita el Asistente de Google.

  1.  Abre tu consola API.AI. En la pestaña Integrations, activa la integración Actions on Google.
  2. En el diálogo emergente, en Additional triggering intents, agrega todos los intents que desees admitir en el Asistente de Google. El sistema fijará automáticamente el intent Welcome como el intent Welcome predeterminado. También puedes hacer clic en SETTINGS en Actions on Google para visualizar el diálogo de configuración en el futuro. Ten en cuenta que el intent inquiry.where requiere la carga de una imagen y no funciona en el Asistente de Google, de modo que no debes agregarlo a la lista de intents de activación. En la sección Nuevo intent para Actions on Google discutimos cómo agregar un nuevo intent para abordar esto. 
  3. Una vez que termines de agregar todos los intents que desees admitir en Google on Actions (por ejemplo, el intent hours-no-context) a la lista de additional triggering intents, toca el botón UPDATE y TEST en la parte inferior. Esto generará un cuadro de color verde. Presiona el botón VIEW para acceder al simulador web de Actions on Google. 
    Si es la primera vez que usas la consola de Actions on Google, te indicará que actives Device Information y Voice & Audio Activity en tu centro de controles de actividad.
    De forma predeterminada, estas configuraciones están desactivadas. Si ya las activaste, no verás el aviso. 
  4. Después de activar estas dos configuraciones, vuelve al simulador. Ya estás listo para probar la integración en el simulador. Comienza escribiendo o diciendo “Talk to my test app”. El simulador responderá con texto del intent Welcome predeterminado. Luego, podrás probar la app como si estuvieras en la consola de prueba API.AI. 

Diferencia entre las API tell() y ask() 

Como mencionamos en la parte 2, existe una diferencia sutil entre las API tell() y ask() cuando implementamos Cloud Function con el Actions on Google SDK. Esto no genera una diferencia notable en las partes 1 y 2, pero sí en la parte 3, cuando integramos Actions on Google. tell() finalizará la conversación y cerrará el micrófono, mientras que ask() mantendrá la conversación abierta y esperará la siguiente entrada del usuario.

Puedes probar la diferencia en el simulador. Si usas tell() en Cloud Functions, deberás decir nuevamente “talk to my test app” después de activar los intents con el webhook de Cloud Functions, como el intent inquiry.parades “Are there any parades today?”. Si usas ask(), aún estarás en la conversación de la app de prueba y no necesitarás volver a decir “talk to my test app”.

Próximos pasos 

Esperamos que en este ejemplo se demuestre la manera de compilar una app simple impulsada por aprendizaje automático. Para obtener más información sobre cómo dar los primeros pasos, te recomendamos probar lo siguiente:

Puedes descargar el código fuente de github.